package javawdw.security;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import javawdw.security.dao.ResourceDao;
import javawdw.security.dao.RoleDao;
import javawdw.security.entity.Resource;
import javawdw.security.entity.Role;
import javawdw.security.spi.IService;

import org.apache.log4j.Logger;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.util.AntUrlPathMatcher;
import org.springframework.security.web.util.UrlMatcher;

public class AccessProvider extends IService implements
		FilterInvocationSecurityMetadataSource {
	private static final Logger logger = Logger
			.getLogger(AccessProvider.class);
	private RoleDao roleDao;
	private ResourceDao resourceDao;

	private UrlMatcher urlMatcher = new AntUrlPathMatcher();

	public Collection<ConfigAttribute> getAttributes(Object object)
			throws IllegalArgumentException {
		if (getCurrentUser() != null) {
			Collection<GrantedAuthority> col = getCurrentUser().getAuthorities();
			for (GrantedAuthority g:col) {
				if (g instanceof Role) {
					Role role = (Role) g;
					if (role.getLevel() == -1) {
						return null;
					}
				}
			}
		}
		if (logger.isDebugEnabled()) {
			logger.debug("getAttributes(Object) - start");
		}
		String url = ((FilterInvocation) object).getRequestUrl();
		List<Resource> resources = resourceDao.find(null);
		Resource resource = null;
		for (Resource temp : resources) {
			if (urlMatcher.pathMatchesUrl(temp.getUrl(), url)) {
				resource = temp;
			}
		}
		if (resource == null) return Collections.emptyList();
		if (resource.getFilterStatus() == 0) return null;
		List<Role> list = null;
		if (resource.getFilterStatus() == -1) {
			list = roleDao.find(null);
		} else {
			list = roleDao.findByResourceUrl(resource.getUrl());
		}
		Collection<ConfigAttribute> atts = new ArrayList<ConfigAttribute>();
		for (Role item : list) {
			ConfigAttribute configAttribute = new SecurityConfig(item.getAuthority());
			atts.add(configAttribute);
		}
		if (logger.isDebugEnabled()) {
			logger.debug("getAttributes(Object) - end");
		}
		return atts;
	}

	public boolean supports(Class<?> clazz) {
		return true;
	}

	public Collection<ConfigAttribute> getAllConfigAttributes() {
		return null;
	}

	public void setRoleDao(RoleDao roleDao) {
		this.roleDao = roleDao;
	}

	public void setResourceDao(ResourceDao resourceDao) {
		this.resourceDao = resourceDao;
	}
}